#pragma once 

#include<ext/hash_map>
#include"net_connection.h"
#include<iostream>

// 解决TCP粘包问题的消息封装头

struct msg_head{
    int msglen; //数据的长度
    int msgid;  //数据的类型ID
};

//消息头的二进制长度，固定数
#define MESSAGE_HEAD_LEN 8

//消息头+消息体的最大长度
#define MESSAGE_LENGTH_LIMIT (65535 - MESSAGE_HEAD_LEN)




//===================== 消息分发路由机制 ==================


typedef void msg_callback(const char *data, uint32_t len, int msgid, net_connection* net_conn, void *args);


//消息路由分发机制
class msg_router {
public:
    // 构造函数
    msg_router():_router(),_args(){

    }

    // 给一个消息ID注册一个对应的回调函数
    int register_msg_router(int msgid, msg_callback* msg_cb, void* args){
        
        if(_router.find(msgid) != _router.end()){
            // 表示当前id对应的回调函数已经存在
            fprintf(stderr,"msgID:%d is already register\n",msgid);
            return -1;
        }

        printf("add msgid:%d callback\n", msgid);

        _router[msgid] = msg_cb;
        _args[msgid] = args;

        return 0;
    }

    // 调用注册的回调函数
    void call(int msgid, const char* data, uint32_t msglen, net_connection *net_conn){
        // std::cout << "msg_router::call msgid:" << msgid << std::endl;
        if(_router.find(msgid) == _router.end()){
            // 表示当前id对应的回调函数不存在
            fprintf(stderr,"msgID:%d is not register\n",msgid);
            return ;
        }

        // 调用具体的回调函数
        msg_callback* cb = _router[msgid];
        void* args = _args[msgid];
        cb(data, msglen, msgid, net_conn, args);
    }

private:
    // 针对消息id对应的回调函数 
    __gnu_cxx::hash_map<int, msg_callback*> _router;

    // 针对消息id对应的回调函数参数
    __gnu_cxx::hash_map<int, void*> _args;
};